package net.maku.events.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.xiaoymin.knife4j.core.util.CollectionUtils;
import lombok.AllArgsConstructor;
import net.maku.events.entity.ActivityKnowledgeContestEntity;
import net.maku.events.enums.ActivityStatusEnum;
import net.maku.events.enums.ActivityTypeEnum;
import net.maku.events.enums.WhetherAddEnum;
import net.maku.events.query.SnapshotApplyQuery;
import net.maku.events.query.UserSnapshotQuery;
import net.maku.events.service.*;
import net.maku.events.vo.ActivityBaseVO;
import net.maku.events.vo.SnapshotApplyVO;
import net.maku.events.vo.UserSnapshotVO;
import net.maku.framework.common.constant.Constant;
import net.maku.framework.common.exception.ServerException;
import net.maku.framework.common.utils.DateUtils;
import net.maku.framework.common.utils.PageResult;
import net.maku.framework.mybatis.service.impl.BaseServiceImpl;
import net.maku.events.entity.ActivitySnapshotEntity;
import net.maku.events.query.ActivitySnapshotQuery;
import net.maku.events.vo.ActivitySnapshotVO;
import net.maku.events.dao.ActivitySnapshotDao;
import net.maku.framework.security.user.SecurityUser;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 随手拍活动
 *
 * @author 阿沐 babamu@126.com
 * @since 1.0.0 2025-03-22
 */
@Service
@AllArgsConstructor
public class ActivitySnapshotServiceImpl extends BaseServiceImpl<ActivitySnapshotDao, ActivitySnapshotEntity> implements ActivitySnapshotService {

    private final UserJoinActivityService userJoinActivityService;

    private final UserSnapshotService userSnapshotService;

    private final UserPointsRecordsService userPointsRecordsService;

    @Override
    public List<ActivityBaseVO> topActivity() {
        List<ActivitySnapshotEntity> entityList = this.list(new LambdaQueryWrapper<ActivitySnapshotEntity>().eq(ActivitySnapshotEntity::getWhetherTop, Constant.ENABLE)
                .eq(ActivitySnapshotEntity::getStatus, Constant.ENABLE));
        if (CollectionUtils.isNotEmpty(entityList)) {
            List<ActivityBaseVO> result = new ArrayList<>();
            entityList.forEach(item -> {
                ActivityBaseVO activityBaseVO = new ActivityBaseVO();
                activityBaseVO.setId(item.getId());
                activityBaseVO.setActivityTitle(item.getActivityTitle());
                activityBaseVO.setThumbnail(item.getActivityBanner());
                activityBaseVO.setTopImg(item.getTopImg());
                activityBaseVO.setActivityStatus(item.getActivityStatus());
                activityBaseVO.setBusinessType(ActivityTypeEnum.SNAPSHOT.getBusinessType());
                result.add(activityBaseVO);
            });
            return result;
        }
        return List.of();
    }

    @Override
    public PageResult<ActivitySnapshotVO> page(ActivitySnapshotQuery query) {
        IPage<ActivitySnapshotEntity> page = baseMapper.selectPage(getPage(query), getWrapper(query));
        List<ActivitySnapshotVO> result = BeanUtil.copyToList(page.getRecords(), ActivitySnapshotVO.class);
        userJoinActivityService.getJoinActivityIdList(ActivityTypeEnum.SNAPSHOT.getBusinessType(), result);
        //判断是否已经完成
        if (CollectionUtils.isNotEmpty(result)) {
            List<Long> alreadyIdList = userSnapshotService.checkSelfEntity(result.stream().map(ActivitySnapshotVO::getId).toList(), ActivityTypeEnum.SNAPSHOT.getBusinessType());
            if (CollectionUtils.isNotEmpty(alreadyIdList)) {
                result.forEach(item -> {
                    if (alreadyIdList.contains(item.getId())) {
                        item.setComplete(true);
                    }
                });
            }
        }

        return new PageResult<>(result, page.getTotal());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void joinActivity(Long id) {
        if (userJoinActivityService.checkJoin(ActivityTypeEnum.SNAPSHOT.getBusinessType(), id)) {
            return;
        }
        ActivitySnapshotEntity activitySnapshotEntity = this.getById(id);
        activitySnapshotEntity.setJoinCount(activitySnapshotEntity.getJoinCount() + 1);
        this.updateById(activitySnapshotEntity);
        userJoinActivityService.save(ActivityTypeEnum.SNAPSHOT.getBusinessType(), id, activitySnapshotEntity.getActivityTitle(), activitySnapshotEntity.getActivityBanner(), activitySnapshotEntity.getActivityStartTime(), activitySnapshotEntity.getActivityEndTime());
    }

    @Override
    public ActivitySnapshotVO getInfoById(Long id) {
        ActivitySnapshotVO activitySnapshotVO = BeanUtil.copyProperties(this.getById(id), ActivitySnapshotVO.class);
        List<ActivitySnapshotVO> result = new ArrayList<>();
        result.add(activitySnapshotVO);
        userJoinActivityService.getJoinActivityIdList(ActivityTypeEnum.SNAPSHOT.getBusinessType(), result);
        List<Long> alreadyIdList = userSnapshotService.checkSelfEntity(Collections.singletonList(id), ActivityTypeEnum.SNAPSHOT.getBusinessType());
        ActivitySnapshotVO snapshotVO = result.get(0);
        if (CollectionUtils.isNotEmpty(alreadyIdList)) {
            snapshotVO.setComplete(true);
        }
        return snapshotVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public double saveUserSnapshot(SnapshotApplyVO vo) {
        ActivitySnapshotEntity entity = this.getById(vo.getSnapshotId());
        if (ObjectUtils.isEmpty(entity)) {
            throw new ServerException("该随手拍活动不存在");
        }
        UserSnapshotVO userSnapshotVO = BeanUtil.copyProperties(vo, UserSnapshotVO.class);
        userSnapshotVO.setSnapshotId(vo.getSnapshotId());
        userSnapshotService.save(null, null, null, ActivityTypeEnum.SNAPSHOT.getBusinessType(), userSnapshotVO);
        //需要审核之后才进行添加积分操作
//        userPointsRecordsService.insertUserPointsRecords(entity.getId(), ActivityTypeEnum.SNAPSHOT.getBusinessType(), entity.getEarningsPoints(), WhetherAddEnum.ADD.getType());
        return entity.getEarningsPoints();
    }

    @Override
    public PageResult<UserSnapshotVO> lookSnapshot(SnapshotApplyQuery query) {
        UserSnapshotQuery snapshotQuery = BeanUtil.copyProperties(query, UserSnapshotQuery.class);
        snapshotQuery.setSnapshotFlag(true);
        return userSnapshotService.page(snapshotQuery);
    }

    private LambdaQueryWrapper<ActivitySnapshotEntity> getWrapper(ActivitySnapshotQuery query) {
        LambdaQueryWrapper<ActivitySnapshotEntity> wrapper = Wrappers.lambdaQuery();
        Long orgId = SecurityUser.getUser().getOrgId();
        wrapper.eq(ActivitySnapshotEntity::getStatus, 1)
                .and(wrapper1 -> {
                    wrapper1.apply("JSON_CONTAINS(join_org_id, CAST({0} AS JSON))", orgId).or().eq(ActivitySnapshotEntity::getOrgId, orgId);
                })
                .orderByDesc(ActivitySnapshotEntity::getUpdateTime);
        return wrapper;
    }

    @Scheduled(cron = "0 0/10 * * * ? ")
    @Transactional(rollbackFor = Exception.class)
    public void updateActivityEndStatus() {
        List<ActivitySnapshotEntity> entityList = this.list(new LambdaQueryWrapper<ActivitySnapshotEntity>().eq(ActivitySnapshotEntity::getActivityStatus, ActivityStatusEnum.BEGIN.getStatus())
                .apply("date_format(activity_end_time,'%Y-%m-%d %H:%i:%s') < date_format ({0},'%Y-%m-%d %H:%i:%s')", DateUtils.format(new Date(), DateUtils.DATE_TIME_PATTERN)));
        if (CollectionUtils.isNotEmpty(entityList)) {
            entityList.forEach(item -> {
                item.setActivityStatus(ActivityStatusEnum.END.getStatus());
            });
            this.saveOrUpdateBatch(entityList);
        }
        List<ActivitySnapshotEntity> notStartList = this.list(new LambdaQueryWrapper<ActivitySnapshotEntity>().eq(ActivitySnapshotEntity::getActivityStatus, ActivityStatusEnum.NOT_START.getStatus())
                .apply("date_format(activity_start_time,'%Y-%m-%d %H:%i:%s') < date_format ({0},'%Y-%m-%d %H:%i:%s')", DateUtils.format(new Date(), DateUtils.DATE_TIME_PATTERN)));
        if (CollectionUtils.isNotEmpty(notStartList)) {
            notStartList.forEach(item -> {
                item.setActivityStatus(ActivityStatusEnum.BEGIN.getStatus());
            });
            this.saveOrUpdateBatch(notStartList);
        }
    }

}